package org.wisdom.ac.domain.user.repository;

import java.util.Collection;
import java.util.List;

import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.lang.Nullable;
import org.wisdom.ac.domain.user.entity.AcUser;
import org.wisdom.ac.domain.user.repository.dao.UserDao;
import org.wisdom.data.jpa.repository.WisdomRepository;

/**
 * 系统用户仓储
 *
 * @author 张智研
 * @date 2022/05/30 14:24
 **/
@SuppressWarnings("NullableProblems")
public interface UserRepository extends WisdomRepository<AcUser, String>, UserDao {

    /**
     * 查询系统用户
     *
     * @author 张智研
     * @date 2022/05/30 14:36
     * @param username 用户名
     * @param enabled 用户状态
     * @return org.wisdom.ac.domain.entity.AcUser
     */
    AcUser findByUserNameAndEnabled(String username, Boolean enabled);

    /**
     * 查询用户列表
     *
     * @author 张智研
     * @date 2022/05/31 08:22
     * @param user 查询条件
     * @param page 页码
     * @param size 大小
     * @param sort 排序
     * @return org.springframework.data.domain.Page<org.wisdom.ac.domain.entity.AcUser>
     */
    default Page<AcUser> findAll(AcUser user, int page, int size, Sort sort) {
        ExampleMatcher matcher =
                ExampleMatcher.matching().withMatcher("staffCode", ExampleMatcher.GenericPropertyMatcher::startsWith)
                        .withMatcher("staffName", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<AcUser> userExample = Example.of(user, matcher);
        return findAll(userExample, PageRequest.of(page, size, sort));
    }

    /**
     * 查询用户列表
     *
     * @author 张智研
     * @date 2022/05/31 08:22
     * @param user 查询条件
     * @param page 页码
     * @param size 大小
     * @return org.springframework.data.domain.Page<org.wisdom.ac.domain.entity.AcUser>
     */
    default Page<AcUser> findAll(AcUser user, int page, int size) {
        return findAll(user, page, size, Sort.unsorted());
    }

    /**
     * 重写方法，解决N+1问题
     *
     * @author 张智研
     * @date 2022/05/31 08:39
     * @param example 查询条件
     * @param pageable 分页条件
     * @return org.springframework.data.domain.Page<S>
     */
    @Override
    @EntityGraph(value = "userWithRole", type = EntityGraph.EntityGraphType.FETCH)
    <S extends AcUser> Page<S> findAll(Example<S> example, Pageable pageable);

    /**
     * 重写方法，解决N+1问题
     *
     * @author 张智研
     * @date 2022/05/31 08:39
     * @param spec 查询条件
     * @param pageable 分页条件
     * @return org.springframework.data.domain.Page<S>
     */
    @Override
    @EntityGraph(value = "userWithRole", type = EntityGraph.EntityGraphType.FETCH)
    Page<AcUser> findAll(@Nullable Specification<AcUser> spec, Pageable pageable);

    /**
     * 根据员工id查询用户账号
     *
     * @author 张智研
     * @date 2022/05/31 09:49
     * @param staffId 员工id
     * @return java.util.List<org.wisdom.ac.domain.entity.AcUser>
     */
    List<AcUser> findByStaffIdIn(Collection<String> staffId);

    /**
     * 根据角色ID查询所有用户
     *
     * @author 张智研
     * @date 2023/05/17 10:13
     * @param roleId 角色ID
     * @param pageable 分页条件
     * @return org.springframework.data.domain.Page<org.wisdom.ac.domain.user.entity.AcUser>
     */
    Page<AcUser> findByUserRolesRoleId(String roleId, Pageable pageable);

    /**
     * 根据角色ID查询所有用户
     * @author 张智研
     * @date 2023/05/17 10:19
     * @param roleId 角色ID
     * @return org.springframework.data.domain.Page<org.wisdom.ac.domain.user.entity.AcUser>
     */
    List<AcUser> findByUserRolesRoleId(String roleId);
}
